package com.glodon.paas.account.dao.mysql;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.provider.ClientAlreadyExistsException;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.NoSuchClientException;
import org.springframework.util.StringUtils;

import com.glodon.paas.account.dao.ClientRegistryDao;
import com.glodon.paas.account.dao.domain.ClientRegistryEntity;
import com.glodon.paas.account.dao.mapper.ClientRegistryEntityMapper;
import com.glodon.paas.account.service.util.PaasRegisteredClientImpl;

public class ClientRegistryDaoMysqlImpl implements ClientRegistryDao {
	@Autowired
	private ClientRegistryEntityMapper clientRegistryEntityMapper;
	
	//@Autowired
	private static String callbackUrls;
	
	public void setCallbackUrls(String callbackUrls) {
		this.callbackUrls = callbackUrls;
	}
	

	
	@Override
	public ClientDetails loadClientByClientId(String clientId)
			throws OAuth2Exception {
		ClientRegistryEntity e = clientRegistryEntityMapper.selectByClientKey(clientId);
		if(!callbackUrls.isEmpty()){
			e.setWebServerRedirectUri(callbackUrls);
		}
		return convert(e);
	}

	@Override
	public void addClientDetails(ClientDetails clientDetails)
			throws ClientAlreadyExistsException {
		clientRegistryEntityMapper.insertSelective(convert(clientDetails));
	}

	@Override
	public void updateClientDetails(ClientDetails clientDetails)
			throws NoSuchClientException {
		clientRegistryEntityMapper.updateByClientKeySelective(convert(clientDetails));
	}

	@Override
	public void updateClientSecret(String clientId, String secret)
			throws NoSuchClientException {
		ClientRegistryEntity e = clientRegistryEntityMapper.selectByClientKey(clientId);
		e.setClientSecret(secret);
		clientRegistryEntityMapper.updateByClientKeySelective(e);
	}

	@Override
	public void removeClientDetails(String clientId)
			throws NoSuchClientException {
		clientRegistryEntityMapper.deleteByClientKey(clientId);
	}

	@Override
	public List<ClientDetails> listClientDetails() {
		List<ClientDetails> clientList = new ArrayList<ClientDetails>();
		List<ClientRegistryEntity> entityList = clientRegistryEntityMapper.selectAll();
		for(ClientRegistryEntity e : entityList){
			clientList.add(convert(e));
		}
		return clientList;
	}

	private ClientDetails convert(ClientRegistryEntity entity){
		if(entity != null){
			PaasRegisteredClientImpl client = new PaasRegisteredClientImpl();
			client.setClientId(entity.getClientKey());
			client.setClientSecret(entity.getClientSecret());
			client.setResourceIds(StringUtils.commaDelimitedListToSet(entity.getResourceIds()));
			client.setScope(StringUtils.commaDelimitedListToSet(entity.getScopes()));
			client.setAuthorizedGrantTypes(StringUtils.commaDelimitedListToSet(entity.getAuthorizedGrantTypes()));
			client.setRegisteredRedirectUri(StringUtils.commaDelimitedListToSet(entity.getWebServerRedirectUri()));
			client.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(entity.getAuthorities()));
			client.setAccessTokenValiditySeconds(entity.getAccessTokenValidity());
			client.setRefreshTokenValiditySeconds(entity.getRefreshTokenValidity());
			client.setDescription(entity.getDescription());
			//client.setAdditionalInformation(entity.getAdditionalInformation());
			return client;
		}
		return null;
	}
	
	private ClientRegistryEntity convert(ClientDetails client){
		if((client != null) && (client instanceof PaasRegisteredClientImpl)){
			ClientRegistryEntity e = new ClientRegistryEntity();
			PaasRegisteredClientImpl c = (PaasRegisteredClientImpl)client;
			e.setClientKey(c.getClientId());
			e.setClientSecret(c.getClientSecret());
			e.setResourceIds(StringUtils.collectionToCommaDelimitedString(c.getResourceIds()));
			e.setScopes(StringUtils.collectionToCommaDelimitedString(c.getScope()));
			e.setAuthorizedGrantTypes(StringUtils.collectionToCommaDelimitedString(c.getAuthorizedGrantTypes()));
			e.setWebServerRedirectUri(StringUtils.collectionToCommaDelimitedString(c.getRegisteredRedirectUri()));
			e.setAuthorities(StringUtils.collectionToCommaDelimitedString(c.getAuthorities()));
			e.setAccessTokenValidity(c.getAccessTokenValiditySeconds());
			e.setRefreshTokenValidity(c.getRefreshTokenValiditySeconds());
			e.setDescription(c.getDescription());
			return e;
		}
		return null;
	}
}
